﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>VarSetStrCapacity - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The VarSetStrCapacity function enlarges a variable's holding capacity or frees its memory. This is not normally needed, but may be used with 动态库调用 or 发送消息 or to optimize repeated concatenation." />
<meta name="ahk:equiv-v1" content="commands/VarSetCapacity.htm" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>VarSetStrCapacity</h1>

<p>增加变量的容量或释放其内存. 一般情况下不需要, 但可以与 <a href="DllCall.htm">动态库调用</a> 或 <a href="SendMessage.htm">发送消息</a> 一起使用, 或者优化重复连接.</p>
<pre class="Syntax">GrantedCapacity := <span class="func">VarSetStrCapacity</span>(TargetVar <span class="optional">, RequestedCapacity</span>)</pre>

<h2 id="Parameters">参数</h2>
<dl>

  <dt>TargetVar</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#variables">变量</a></p>
    <p>变量的引用. 例如: <code>VarSetStrCapacity(MyVar, 1000)</code>. 这也可以是动态变量, 例如 <code>数组%i%</code> 或是<a href="../Functions.htm#ByRef">函数的 ByRef 参数</a>.</p>
  </dd>

  <dt>RequestedCapacity</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>如果省略, 则函数将返回变量当前的容量且不会改变其的内容. 否则, 变量中的所有内容将会丢弃(变量被置空).</p>
    <p>指定 <em>RequestedCapacity</em> 为调整后变量所能容纳的字节数. <em>RequestedCapacity</em> 不包括内部零终止符. 例如, 指定 1 将允许变量在其内部结束符之外最多容纳一个字符. 注意: 如果脚本稍后给它分配一个更大的值, 变量将自动展开.</p>
    <p>因此可以经常简单地调用此函数来确保变量占用最小的空间, 出于性能的考虑, 它只在 <em>RequestedCapacity</em> 为 0 的时候才会缩小变量. 换句话说, 如果变量的容量已经大于 <em>RequestedCapacity</em>, 它就不会被缩小(但为了保持一致性, 变量会被置空).</p>
    <p>因此, 要显式地缩小变量, 首先请使用 <code>VarSetStrCapacity(Var, 0)</code> 释放它占用的内存, 然后使用 <code>VarSetStrCapacity(Var, NewCapacity)</code> -- 或者简单地让它自动按需从零扩展.</p>
    <p>出于性能考虑, 要释放一个原来容量小于 64 字符的变量可能会没有效果, 因为它的内存是永久类型的. 在这种情况下, 会返回当前容量, 而不是 0.</p>
    <p>出于性能考虑, 容量小于 4096 字节的变量的内存不能通过赋值空字符串的方法来释放(例如 <code>变量 := &quot;&quot;</code>). 然而, <code>VarSetStrCapacity(Var, 0)</code> 可释放它.</p>
    <p id="neg1">为 <em>RequestedCapacity</em> 指定 -1, 将变量内部存储的字符串长度更新为其当前内容的长度. 这在字符串被间接改变的情况下很有用, 比如通过 <a href="DllCall.htm">动态库调用</a> 或 <a href="SendMessage.htm">发送消息</a> 传递其<a href="StrPtr.htm">地址</a>. 在这种模式下, VarSetStrCapacity 返回的是长度而不是容量.</p>
  </dd>

</dl>

<h2 id="Return_Value">返回值</h2>
<p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
<p>该函数返回 Var 现在可以容纳的字符数, 该字符数将大于或等于 <em>RequestedCapacity</em>.</p>

<h2 id='Failure'>失败</h2>
<p>在以下任何一种情况下都会抛出异常:</p>
<ul>
  <li><em>VarName</em> 不是一个有效的变量引用. 不可能通过引用传递一个<a href="../Objects.htm#Usage_Objects">对象属性</a>或<a href="../Variables.htm#BuiltIn">内置变量</a>, 因此不能将其传递给该函数.</li>
  <li>请求的容量太大, 无法容纳在脚本可用的任何一个连续的内存块中. 在极少数情况下, 这可能是由于系统内存耗尽所致.</li>
  <li><em>RequestedCapacity</em> 小于 -1 或大于当前平台理论上可以支持的容量.</li>
</ul>

<h2 id="Remarks">备注</h2>
<p><a href="../objects/Buffer.htm">Buffer</a> 对象在处理二进制数据, 结构体, 动态库调用 和类似的东西时, 提供了卓越的清晰度和灵活性. 例如, Buffer 对象可以分配给一个属性或数组元素, 或者传递给一个函数或从一个函数返回, 而不需要复制其内容.</p>
<p>在通过渐进式连接的方式构建一个字符串时, 可以使用这个函数来提高性能. 这是因为当你对字符串的最终长度有一定了解时, 可以避免多次自动调整大小. 在这种情况下, <em>RequestedCapacity</em> 不需要太准确: 如果容量太小, 性能仍然会得到提高, 当容量用完后, 变量将开始自动扩展. 如果容量过大, 则会浪费部分内存, 但只是暂时的, 因为所有的内存都可以在操作后通过 <code>VarSetStrCapacity(Var, 0)</code> 或 <code>变量 := &quot;&quot;</code> 来释放.</p>

<h2 id="Related">相关</h2>
<p><a href="BufferAlloc.htm">创建缓冲区</a>, <a href="../objects/Buffer.htm">Buffer 对象</a>, <a href="DllCall.htm">动态库调用</a>, <a href="NumPut.htm">置数值</a>, <a href="NumGet.htm">获取数值</a></p>
<h2 id="Examples">示例</h2>
<div class="ex" id="ExBasic">
<p><a href="#ExBasic">#1</a>: 通过确保 <em>MyVar</em> 有足够的工作空间来优化.</p>
<pre>VarSetStrCapacity(MyVar, 5120000)  <em>; ~10 MB</em>
循环
{
    <em>; ...</em>
    MyVar .= StringToConcatenate
    <em>; ...</em>
}</pre>
</div>

<div class="ex" id="ExString">
<p><a href="#ExString">#2</a>: 使用一个变量通过 <a href="DllCall.htm">动态库调用</a> 从外部函数接收一个字符串. (注意, 使用 <a href="BufferAlloc.htm#ExString">创建缓冲区</a> 可能是首选; 尤其是在处理非 Unicode 字符串时.)</p>
<pre>max_chars := 10

循环 2
{
    <em>; 分配用于 动态库调用 的空间.</em>
    VarSetStrCapacity(buf, max_chars)

    如果 (内_循环次数 = 1)
        <em>; 通过 动态库调用 间接修改变量.</em>
        动态库调用("wsprintf", <span class="red">"Ptr", 字符串指针(buf)</span>, "Str", "0x%08x", "UInt", 4919, "CDecl")
    否则
        <em>; 使用 "str" 来自动更新长度:</em>
        动态库调用("wsprintf", <span class="blue">"Str", buf</span>, "Str", "0x%08x", "UInt", 4919, "CDecl")

    <em>; 连接字符串以演示为什么需要更新长度:</em>
    wrong_str := buf . "&lt;end&gt;"
    wrong_len := 字符串长度(buf)

    <em>; 更新变量的长度.</em>
    VarSetStrCapacity(buf, -1)

    right_str := buf . "&lt;end&gt;"
    right_len := 字符串长度(buf)

    信息框
    (
    "Before updating
      字符串: " wrong_str "
      Length: " wrong_len "

    After updating
      字符串: " right_str "
      Length: " right_len
    )
}
</pre>
</div>

</body>
</html>